package tp.tecnicasdisenio.dao.impl.jdbc;

import java.sql.SQLException;
import java.util.ArrayList;

import tp.tecnicasdisenio.dao.DaoException;
import tp.tecnicasdisenio.dao.GrupoDaoInterface;
import tp.tecnicasdisenio.model.entity.Alumno;
import tp.tecnicasdisenio.model.entity.Cuatrimestre;
import tp.tecnicasdisenio.model.entity.Grupo;
import tp.tecnicasdisenio.model.entity.Grupo.ClaveGrupo;
import tp.tecnicasdisenio.model.entity.Materia;
import tp.tecnicasdisenio.util.EntityUtil;

public class GrupoDao extends DaoAbstract implements GrupoDaoInterface{

	private static GrupoDao instancia = null;
	
	private String nombreTabla = "grupos";
	
	private GrupoDao(){}
	
	public static GrupoDao getInstance(){
		if (instancia == null)
			instancia = new GrupoDao();
		return instancia;
	}
	
	private ArrayList<Grupo> obtenerGrupo(ClaveGrupo id, boolean unoSolo) {
		ArrayList<Grupo> resultado = null;
		
		try {
			String queryString = "SELECT * FROM " + this.nombreTabla;
			
			if (unoSolo)
				queryString = queryString.concat(" WHERE anio=? AND codigo_materia=? AND cuatrimestre=? AND nro_grupo=?");

			connection = this.getConnection();
			preparedStatement = connection.prepareStatement(queryString);
			
			if (unoSolo) {
				preparedStatement.setInt(1, id.getCuatrimestre().getAnio());
				preparedStatement.setString(2, id.getMateria().getCodigo());
				preparedStatement.setInt(3, new Integer(id.getCuatrimestre().getCuatrimestre()));
				preparedStatement.setInt(4, id.getNumero());
			}
			
			resultSet = preparedStatement.executeQuery();
			
			resultado = new ArrayList<Grupo>();
			Grupo grupoDB = null;
			ClaveGrupo clave = null;
			Cuatrimestre cuat = null;
			
			while (resultSet.next()) {
				grupoDB = new Grupo();
				cuat = new Cuatrimestre();
				clave = new ClaveGrupo();
				
				clave.setMateria(MateriaDao.getInstance().getPorId(resultSet.getString("codigo_materia")));
				clave.setNumero(resultSet.getInt("nro_grupo"));
				
				cuat.setAnio(resultSet.getInt("anio"));
				cuat.setCuatrimestre(((Integer)resultSet.getInt("cuatrimestre")).toString());
				clave.setCuatrimestre(cuat);
				
				grupoDB.setClaveGrupo(clave);
				resultado.add(grupoDB);
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
			throw (new DaoException(e));
		} finally {
			try {
				if (resultSet != null)
					resultSet.close();
				if (preparedStatement != null)
					preparedStatement.close();
				if (connection != null)
					connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return resultado;
	}
	
	@Override
	public Grupo getPorId(ClaveGrupo id) {
		ArrayList<Grupo> listaGrupos = this.obtenerGrupo(id, true); 
		Grupo grupoDB = null;
		if (!listaGrupos.isEmpty())
			grupoDB = listaGrupos.iterator().next();
		return grupoDB;
	}

	@Override
	public ArrayList<Grupo> obtenerTodos() {
		return (this.obtenerGrupo(null, false));
	}

	@Override
	public void borrar(Grupo entidad) {
		try {
			String queryString = "DELETE FROM " + this.nombreTabla + " WHERE cuatrimestre=? AND " +
					"anio=? AND nro_grupo=? AND codigo_materia=?";
			connection = getConnection();
			preparedStatement = connection.prepareStatement(queryString);
			preparedStatement.setInt(1, new Integer(entidad.getClaveGrupo().getCuatrimestre().getCuatrimestre()));
			preparedStatement.setInt(2, entidad.getClaveGrupo().getCuatrimestre().getAnio());
			preparedStatement.setInt(3, entidad.getClaveGrupo().getNumero());
			preparedStatement.setString(4, entidad.getClaveGrupo().getMateria().getCodigo());
			
			preparedStatement.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
			throw (new DaoException(e));
		} finally {
			try {
				if (preparedStatement != null)
					preparedStatement.close();
				if (connection != null)
					connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void actualizar(Grupo entidad) {
		throw (new RuntimeException("no soportado"));
	}

	@Override
	public void insertar(Grupo entidad) {
		try {
			String queryString = "INSERT INTO " + this.nombreTabla + "(cuatrimestre, anio, nro_grupo, codigo_materia) VALUES(?,?,?,?)";
			connection = getConnection();
			preparedStatement = connection.prepareStatement(queryString);
			preparedStatement.setInt(1, new Integer(entidad.getClaveGrupo().getCuatrimestre().getCuatrimestre()));
			preparedStatement.setInt(2, entidad.getClaveGrupo().getCuatrimestre().getAnio());
			preparedStatement.setInt(3, entidad.getClaveGrupo().getNumero());
			preparedStatement.setString(4, entidad.getClaveGrupo().getMateria().getCodigo());
			
			preparedStatement.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
			throw (new DaoException(e));
		} finally {
			try {
				if (preparedStatement != null)
					preparedStatement.close();
				if (connection != null)
					connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void altaEnGrupo(Grupo grupoNuevo, Alumno alumno) {
		try {
			String queryString = "INSERT INTO integra_grupo (padron, cuatrimestre, anio, nro_grupo, codigo_materia) VALUES(?,?,?,?,?)";
			connection = getConnection();
			preparedStatement = connection.prepareStatement(queryString);
			preparedStatement.setInt(1, new Integer(alumno.getPadron()));
			preparedStatement.setInt(2, new Integer(grupoNuevo.getClaveGrupo().getCuatrimestre().getCuatrimestre()));
			preparedStatement.setInt(3, grupoNuevo.getClaveGrupo().getCuatrimestre().getAnio());
			preparedStatement.setInt(4, grupoNuevo.getClaveGrupo().getNumero());
			preparedStatement.setString(5, grupoNuevo.getClaveGrupo().getMateria().getCodigo());
			
			preparedStatement.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
			throw (new DaoException(e));
		} finally {
			try {
				if (preparedStatement != null)
					preparedStatement.close();
				if (connection != null)
					connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public Grupo getGrupoDel(Alumno alumno, Materia materia, Cuatrimestre cuatrimestre) {
		Grupo resultado = null;
		try {
			String queryString = "SELECT * FROM grupos WHERE nro_grupo IN " +
					"(SELECT nro_grupo FROM integra_grupo WHERE padron=? AND codigo_materia=? AND anio=? AND cuatrimestre=?)";
			connection = getConnection();
			preparedStatement = connection.prepareStatement(queryString);
			preparedStatement.setInt(1, new Integer(alumno.getPadron()));
			preparedStatement.setString(2, materia.getCodigo());
			preparedStatement.setInt(3, cuatrimestre.getAnio());
			preparedStatement.setInt(4, new Integer(cuatrimestre.getCuatrimestre()));

			resultSet = preparedStatement.executeQuery();
			
			if (resultSet.next()) {
				String cuatrimestreGrupo = ((Integer)resultSet.getInt("cuatrimestre")).toString();
				Cuatrimestre cuat = EntityUtil.crearCuatrimestre(cuatrimestreGrupo, resultSet.getInt("anio"));
				
				ClaveGrupo clave = new ClaveGrupo();
				
				clave.setMateria(MateriaDao.getInstance().getPorId(resultSet.getString("codigo_materia")));
				clave.setNumero(resultSet.getInt("nro_grupo"));
				clave.setCuatrimestre(cuat);
				
				resultado = new Grupo();
				resultado.setClaveGrupo(clave);
			}
		} catch (SQLException e) {
			e.printStackTrace();
			throw (new DaoException(e));
		} finally {
			try {
				if (preparedStatement != null)
					preparedStatement.close();
				if (connection != null)
					connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return resultado;
	}
}
